//
//  QkdAudioRecorderPluginManager.m
//  qkd_audio_recorder
//
//  Created by Luoei on 2020/1/13.
//

#import "QkdAudioRecorderPluginManager.h"
#import "PLCAudioRecorderHelper.h"
#import "XBAudioUnitRecorder.h"
#import "MP3Encoder.h"
#import "XBDataWriter.h"
#import <Accelerate/Accelerate.h>
#import "XBAudioTool.h"
#import "XBAudioUploader.h"

@interface QkdAudioRecorderPluginManager()

@property(nonatomic,strong) FlutterMethodChannel *channel;

@property(nonatomic,strong) XBAudioUnitRecorder * recorder;

@property(nonatomic,strong) MP3Encoder * mp3Encoder;

@property(nonatomic,strong) XBDataWriter * dataWriter;

/// 录音类型 // 1 - 实时 2 - 串连
@property(nonatomic,assign) NSInteger  recorderType;


@end

@implementation QkdAudioRecorderPluginManager

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar{
    
    FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"qkd_audio_recorder" binaryMessenger:[registrar messenger]];
    QkdAudioRecorderPluginManager *plugin = [[QkdAudioRecorderPluginManager alloc]init];
    plugin.channel = channel;
    [registrar addMethodCallDelegate:plugin channel:channel];
}

-(instancetype)init{
    if (self = [super init]){
        
    }
    return self;
}

-(void)loadEvents{
    self.recorderType = [[NSUserDefaults standardUserDefaults] integerForKey:@"QKDAudioRecorderType"];
    if (!self.recorderType) self.recorderType = 2;
}

- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result{
    
    [XBAudioTool log:XBAudioLogLevelInfo message:@"handleMethodCall" parameters:@{@"method": call.method ?: @"", @"args": call.arguments ?: @""}];
    
    if ([call.method isEqualToString:@"getPlatformVersion"] ) {
        result([NSString stringWithFormat:@"iOS %@", [UIDevice currentDevice].systemVersion]);
    }else if ([call.method isEqualToString:@"start"] ) {
        [self loadEvents];
        
        [XBAudioTool log:XBAudioLogLevelInfo message:[NSString stringWithFormat:@"start... type: %lu", self.recorderType] parameters:nil];
        
        if (self.recorderType == 2){
            PLCAudioRecorderHelper *recorderHelper = [PLCAudioRecorderHelper  sharedPLCAudioRecorderHelper];
            recorderHelper.peakPower = YES;
            recorderHelper.peakPowerBlock = ^(NSNumber *peak) {
    //            NSLog(@"recorderHelper....%@", peak);
                [self.channel invokeMethod:@"onRecordSound" arguments:peak];
            };
            [recorderHelper startAudioRecorder];
        }else{
            __weak typeof(self) weakSelf=self;
            [self deleteFileAtPath:mp3StroePath];
            if (!self.recorder){
            self.recorder = [[XBAudioUnitRecorder alloc] initWithRate:XBAudioRate_11k bit:XBAudioBit_16 channel:XBAudioChannel_1];
            self.mp3Encoder = [[MP3Encoder alloc] initWithSampleRate:XBAudioRate_11k channels:1 bitRate:16];
            self.dataWriter = [[XBDataWriter alloc] init];
            self.recorder.bl_outputFull = ^(XBAudioUnitRecorder *player, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *bufferList, float peakPower) {

                dispatch_async(dispatch_get_main_queue(), ^{
                    //转换成0-120，120为高峰
                    NSInteger peak = (peakPower + 50) * 3;
                    if (peak < 0 ) peak = 0;
                    if (peak > 120) peak = 120;
            //                NSLog(@"Audio Recorder demonVol - %f -- %lu ", peakPower, peak);
                   [weakSelf.channel invokeMethod:@"onRecordSound" arguments:@(peak)];
                });
                AudioBuffer buffer = bufferList->mBuffers[0];
                [weakSelf.mp3Encoder encodePCMData:buffer.mData len:buffer.mDataByteSize completeBlock:^(unsigned char *encodedData, int len) {
                    [weakSelf.dataWriter writeBytes:encodedData len:len toPath:mp3StroePath];
            //                    [XBAudioTool log:XBAudioLogLevelVerbose message:@"writeBytes" parameters:nil];
                }];
            };
            self.recorder.bl_uploaderComplete = ^(NSString *url, NSInteger result){
                dispatch_async(dispatch_get_main_queue(), ^{
                    [XBAudioTool log:XBAudioLogLevelInfo message:@"onUploadComplete" parameters:@{@"url": url ?: @"", @"code": @(result)}];
                    [weakSelf.channel invokeMethod:@"onUploadComplete" arguments: @{@"url": url, @"code": @(result)}];
                });
            };
            }
            [self.recorder start];
        }
    }else if ([call.method isEqualToString:@"stop"] ) {
        [XBAudioTool log:XBAudioLogLevelInfo message:[NSString stringWithFormat:@"stop... type: %lu", self.recorderType] parameters:nil];
        if (self.recorderType == 2){
            __weak typeof(self) weakSelf=self;
            [[PLCAudioRecorderHelper  sharedPLCAudioRecorderHelper] endAudioRecorderWithTranscodingBlock:^(NSString *path) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [XBAudioTool log:XBAudioLogLevelInfo message:@"onRecordComplete" parameters:@{@"path": path ?: @""}];
                    [self.channel invokeMethod:@"onRecordComplete" arguments:path ?: @""];
                });
                
                //开始上传
                if(path){
                    XBAudioUploader *uploader = [[XBAudioUploader alloc]init];
                    uploader.completeBlock = ^(NSString *url, NSInteger result) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            [XBAudioTool log:XBAudioLogLevelInfo message:@"onUploadComplete" parameters:@{@"url": url ?: @"", @"code": @(result)}];
                            [weakSelf.channel invokeMethod:@"onUploadComplete" arguments: @{@"url": url, @"code": @(result)}];
                        });
                    };
                    [uploader uploadWithPath:path];
                }else{
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [XBAudioTool log:XBAudioLogLevelError message:@"录音无效" parameters:nil];
                        [weakSelf.channel invokeMethod:@"onUploadComplete" arguments: @{@"code": @(1)}];
                    });
                }
                
            }];
        }else{
            [self stop];
            [XBAudioTool log:XBAudioLogLevelInfo message:@"onRecordComplete" parameters:@{@"path": mp3StroePath}];
            [self.channel invokeMethod:@"onRecordComplete" arguments:mp3StroePath];
        }
        
    }else if ([call.method isEqualToString:@"destory"] ) {
        [self.recorder destory];
    }else if ([call.method isEqualToString:@"debug"] ) {
        
    }
}

- (void)stop{
//    self.mp3Encoder = nil;
//    self.dataWriter = nil;
    [self.recorder stop];
//    self.recorder = nil;
}

- (void)deleteFileAtPath:(NSString *)path{
    if ([[NSFileManager defaultManager] fileExistsAtPath:path])
    {
        [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
    }
}


@end
